package com.sofwin.aspect;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sofwin.annotation.Log;
import com.sofwin.pojo.SysOperatorLog;
import com.sofwin.pojo.SysUser;
import com.sofwin.service.OperatorLogService;
import com.sofwin.service.UserService;
import com.sofwin.util.CustomerUtil;
import net.bytebuddy.implementation.bytecode.Throw;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.assertj.core.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;

/**
 * @packageName: com.sofwin.aspect
 * @author: andyliu
 * @date: 2022/5/10 9:41
 * @email 115176513@qq.com
 * @description: TODO
 */
@Aspect
@Component
public class LogAspect {
    @Autowired
    private OperatorLogService logService;
    @Autowired
    private UserService userService;
    @Pointcut("@annotation(com.sofwin.annotation.Log)")
    public void test01(){

    }
    @AfterReturning(pointcut = "test01()",returning ="result" )
    public void afterReturning(JoinPoint joinPoint,Object result) throws JsonProcessingException {
        // 获取注解的相关信息
        // 1.获取目标方法
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Method method = signature.getMethod();
        Log log = method.getAnnotation(Log.class);
        System.out.println(log.module()+","+log.operatorType());
        SysOperatorLog logger = new SysOperatorLog();
        logger.setModule(log.module());
        logger.setOperatorType(log.operatorType());
        logger.setOperatorDate(DateUtil.formatAsDatetime(new Date()));
        logger.setOperatorMethod(method.getName());
        // 如何获取request
        ObjectMapper objectMapper = new ObjectMapper();
        String str = objectMapper.writeValueAsString(result);
        logger.setRetrunValue(str);
        logger.setStatus(0);
        Subject subject= SecurityUtils.getSubject();
        String loginName = subject.getPrincipal().toString();
        SysUser user = userService.checkLogin(loginName);
        logger.setUserId(user.getUserId());
        // 获取request对象
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null){
            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
            logger.setOperatorIp(CustomerUtil.getIpAddress(request));
            logger.setUrl(request.getRequestURL().toString());
            logger.setRequestMethod(request.getMethod());
            Map<String, String[]> map = request.getParameterMap();
            if(map!=null){
                logger.setRequestParam(objectMapper.writeValueAsString(map));
            }

        }
        logService.saveOperatorLog(logger);
    }

    @AfterThrowing(pointcut = "test01()",throwing ="ex" )
    public void afterThrowing(JoinPoint joinPoint, Throwable ex) throws JsonProcessingException {
        // 获取注解的相关信息
        // 1.获取目标方法
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Method method = signature.getMethod();
        Log log = method.getAnnotation(Log.class);
        System.out.println(log.module()+","+log.operatorType());
        SysOperatorLog logger = new SysOperatorLog();
        logger.setModule(log.module());
        logger.setOperatorType(log.operatorType());
        logger.setOperatorDate(DateUtil.formatAsDatetime(new Date()));
        logger.setOperatorMethod(method.getName());
        // 如何获取request
        ObjectMapper objectMapper = new ObjectMapper();
        String str = objectMapper.writeValueAsString(ex);
        logger.setRetrunValue(str);
        logger.setStatus(1);
        Subject subject= SecurityUtils.getSubject();
        String loginName = subject.getPrincipal().toString();
        SysUser user = userService.checkLogin(loginName);
        logger.setUserId(user.getUserId());
        //
        logService.saveOperatorLog(logger);
    }
}
